import java.io.IOException;
import java.io.InputStream;

import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import javax.xml.xpath.*;


import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class XPathExample {
	public static void main(String[] args)
		throws ParserConfigurationException, SAXException,
		IOException, XPathExpressionException {
			//load the document into a DOM Document
			DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
			domFactory.setNamespaceAware(true); // never forget this!
			DocumentBuilder builder = domFactory.newDocumentBuilder();
			Document doc = builder.parse("books.xml");
			//create an XPath factory
			XPathFactory factory = XPathFactory.newInstance();
			//create an XPath Object
			XPath xpath = factory.newXPath();
			//make the XPath object compile the XPath expression
			XPathExpression expr = xpath.compile("//book[author='Neal Stephenson']/title/text()");
			//evaluate the XPath expression
			Object result = expr.evaluate(doc, XPathConstants.NODESET);
						
			NodeList nodes = (NodeList) result;
			//print the output
			for (int i = 0; i < nodes.getLength(); i++) {
				System.out.println(nodes.item(i).getNodeValue());
			}
			
			//evaluate an XPath expression without compiling
			Object result1 = xpath.evaluate("/inventory/book/descendant-or-self::node()",doc,XPathConstants.NODESET);
			System.out.println("result1:");
			NodeList nodes1 = (NodeList) result1;
			
			DemoMain demo = new DemoMain();
			demo.displayNode(nodeToString(nodes1.item(0)));
			
			for (int i = 0; i < nodes1.getLength(); i++) {
				System.out.println("*******");
				System.out.println(nodeToString(nodes1.item(i)));
				System.out.println("*******");
			}
			
			//evaluate an XPath expression without compiling
			Object result11 = xpath.evaluate("inventory/book[id(\"b3\")]",doc,XPathConstants.NODESET);
			System.out.println("result1:");
			NodeList nodes11 = (NodeList) result11;
			for (int i = 0; i < nodes11.getLength(); i++) {
				result11 = xpath.evaluate("title/text()",nodes11.item(i),XPathConstants.NODESET);
				NodeList nodes2 = (NodeList) result11;
				for (int j = 0; j < nodes2.getLength(); j++) {
					System.out.println(nodes2.item(j).getNodeValue());
				}
			}
		}
	
	private static String nodeToString(Node node) {
		StringWriter sw = new StringWriter();
		try {
		Transformer t = TransformerFactory.newInstance().newTransformer();
		t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		t.transform(new DOMSource(node), new StreamResult(sw));
		} catch (TransformerException te) {
		System.out.println("nodeToString Transformer Exception");
		}
		return sw.toString();
		}
	}